/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MNetSockets.CmdChanel;

import java.io.IOException;
import java.net.*;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author wcss
 */
public class CmdServer implements Runnable {

    private ServerSocket selfsocket = null;
    private IDataReader dataReadEvent;
    private IConnectionState connectionEvent;
    public int listenPort = 0;
    private Thread acceptThread = null;
    public Hashtable<String, CmdClient> connectionList = new Hashtable<String, CmdClient>();

    public void handleDataRead(Object data) {
        if (getDataReadEvent() != null) {
            this.getDataReadEvent().dataRead(this, data);
        }
    }

    public void handleConnectionState(String state, String tag) {
        if (getConnectionEvent() != null) {
            getConnectionEvent().changeState(this, state, tag);
        }
    }

    public void listen(int port) throws Exception {
        this.listenPort = port;

        selfsocket = new ServerSocket(port);
        acceptThread = new Thread(this);
        acceptThread.setDaemon(true);
        acceptThread.start();

        handleConnectionState("listen to " + port, null);
    }

    public void close() {
        try {
            selfsocket.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        Iterator iter;
        iter = this.connectionList.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            ((CmdClient) entry.getValue()).close();
        }
    }
    private int nowCount = 0;

    @Override
    public void run() {
        while (this.selfsocket != null) {
            try {
                Socket skt = this.selfsocket.accept();
                nowCount++;                
                CmdClient ccc = new CmdClient(this,nowCount + "", skt, this.getDataReadEvent(), this.getConnectionEvent());                
                this.connectionList.put(nowCount + "", ccc);
            } catch (Exception ex) {
                Logger.getLogger(CmdServer.class.getName()).log(Level.SEVERE, null, ex);
                break;
            }

            try {
                Thread.sleep(20);
            } catch (InterruptedException ex) {
                Logger.getLogger(CmdServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }


        try {
            this.handleConnectionState("closing", null);
            this.close();
            this.handleConnectionState("closed", null);
        } catch (Exception ex) {
            Logger.getLogger(CmdServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * @return the dataReadEvent
     */
    public IDataReader getDataReadEvent() {
        return dataReadEvent;
    }

    /**
     * @param dataReadEvent the dataReadEvent to set
     */
    public void setDataReadEvent(IDataReader dataReadEvent) {
        this.dataReadEvent = dataReadEvent;
    }

    /**
     * @return the connectionEvent
     */
    public IConnectionState getConnectionEvent() {
        return connectionEvent;
    }

    /**
     * @param connectionEvent the connectionEvent to set
     */
    public void setConnectionEvent(IConnectionState connectionEvent) {
        this.connectionEvent = connectionEvent;
    }
}
